package com.codi.api.controller.h5;

import com.codi.api.validation.AccountValidation;
import com.codi.base.config.ConfigurationMgr;
import com.codi.base.log.annotation.Loggable;
import com.codi.base.util.ListUtil;
import com.codi.base.util.MD5;
import com.codi.base.util.StringUtil;
import com.codi.base.web.RequestUtils;
import com.codi.bus.constant.GlobalConstant;
import com.codi.bus.core.domain.BankName;
import com.codi.bus.core.domain.User;
import com.codi.bus.core.domain.UserBank;
import com.codi.bus.core.fund.FundErrorConst;
import com.codi.bus.core.resultModel.*;
import com.codi.bus.core.service.BankService;
import com.codi.bus.core.service.BranchBankService;
import com.codi.bus.core.service.QueryService;
import com.codi.bus.core.service.UserService;
import com.codi.bus.core.service.model.BankModel;
import com.codi.bus.core.util.BaseResultUtil;
import com.codi.bus.exception.BaseException;
import com.codi.fcloud.ufx.HsResponseUtil;
import com.codi.message.constant.ErrorConstant;
import com.codi.message.util.MessageUtil;
import com.codi.trade.service.LoginAcctService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 银行接口相关
 *
 * @author mifj
 * @date 2018年3月13日15:54:51
 */
@RestController
@RequestMapping("/h5/bank")
@Slf4j
public class H5BranchBankController {

    @Autowired
    private BranchBankService branchBankService;

    @Autowired
    private AccountValidation accountValidation;
    @Autowired
    private UserService userService;
    @Autowired
    private QueryService queryService;
    @Autowired
    private LoginAcctService loginAcctService;
    @Autowired
    private BankService bankService;

    /**
     * 省份
     */
    @GetMapping("/province")
    @Loggable
    public BaseResult getProvince() {
        List<String> provinces = branchBankService.getProvince();
        BaseResult result = new BaseResult();
        result.setResult(provinces);
        return result;
    }

    /**
     * 地级市
     */
    @GetMapping("/city")
    @Loggable
    public BaseResult getCityByProvince(String provinceName) {
        List<String> citys = branchBankService.getCity(provinceName);
        BaseResult result = new BaseResult();
        result.setResult(citys);
        return result;
    }

    /**
     * 一个市的一种银行
     */
    @GetMapping("/cityBank")
    @Loggable
    public BaseResult getBankByCity(String cityName, String bankName) {
        List<BankName> cityBanks = branchBankService.getCityBank(cityName, bankName);
        BaseResult result = new BaseResult();
        result.setResult(cityBanks);
        return result;
    }

    /**
     * 搜索支行
     *
     * @param bankName 银行名称
     * @param word     关键字
     * @return
     */
    @GetMapping("/fundBank")
    @Loggable
    public BaseResult getBankByWord(String bankName, String word) {
        List<BankName> fundBanks = branchBankService.getFundBank(bankName, word);
        BaseResult result = new BaseResult();
        result.setResult(fundBanks);
        return result;
    }

    /**
     * 支行修改
     *
     * @param vcBranchbank  支行联行号
     * @param vcBankname    支行名称
     * @param tradePassword app内交易密码
     * @return
     */
    @PostMapping("/setBank")
    @Loggable
    public BaseResult setBranchBank(HttpServletRequest request, String vcBranchbank, String vcBankname, String tradePassword) {
        BaseResult result = null;
        try {
            result = accountValidation.setBranchBankValidate(vcBranchbank, tradePassword);
            if (result != null) {
                return result;
            }
            Long userId = Long.valueOf(RequestUtils.getHeader(request, "userid"));
            return branchBankService.setBranchBank(userId, vcBranchbank, vcBankname, tradePassword);
        } catch (Exception e) {
            log.error("h5接口:/h5/bank/setBank 错误信息:{}", e.getMessage());
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 发送验证码
     *
     * @param request
     * @param entity
     * @param bankEntity
     * @param isOpen
     * @throws BaseException
     */
    @PostMapping("/pay-sign-one")
    @Loggable
    public BaseResult paySignOne(HttpServletRequest request, User entity, UserBank bankEntity, @RequestParam boolean isOpen) throws BaseException {
        Long userId = Long.valueOf(RequestUtils.getHeader(request, "userid"));
        // 验证输入
        ConfigurationMgr mgr = ConfigurationMgr.getInstance();
        bankEntity.setCapitalMode(mgr.getString("capital_mode", GlobalConstant.CAPITAL_MODE_EPAY));

        PaySignResult result = accountValidation.validatePaySign(entity, bankEntity, isOpen);
        if (result != null) {
            return result;
        }

        // 身份证转成大写
        entity.setUserCard(entity.getUserCard().toUpperCase());
        entity.setUserId(userId);
        bankEntity.setUserId(userId);
        bankEntity.setUserBankOwner(entity.getUserName());

        result = userService.paySign_Step_One(entity, bankEntity);
        if (!result.getSuccess() && StringUtil.isEmpty(result.getErrorMessage())) {
            result.setErrorMessage(MessageUtil.getErrorMessage(result.getErrorCode(), null));
        }
        return result;
    }

    /**
     * 判断是否需要修改支行
     * true 代表需要修改
     */
    @GetMapping("/isBranch")
    @Loggable
    public BaseResult isBranch(HttpServletRequest request) {
        Long userId = Long.valueOf(RequestUtils.getHeader(request, "userid"));
        BankModel bankModel = userService.getChangeBranch(userId);
        BaseResult result = new BaseResult();
        result.setResult(bankModel);
        return result;
    }


    /**
     * 新增银行卡
     */
    @PostMapping("/add_bank")
    @Loggable
    public BaseResult addBank(@RequestParam String userName, @RequestParam String userCard, @RequestParam String tradePassword,
                              @RequestParam String bankCode, @RequestParam String bankName, @RequestParam String userBankNo,
                              @RequestParam String userBankMobile, @RequestParam String originalSerialNo,
                              @RequestParam String smsSerialNo, @RequestParam String mobileCode, @RequestParam String vcBranchbank,
                              @RequestParam boolean isOpen, @RequestParam String vcBankname,
                              HttpServletRequest request) {
        AccountOpenResult result = new AccountOpenResult();


        Long userId = Long.valueOf(RequestUtils.getHeader(request, "userid"));
        User user = userService.getUser(userId);

        BaseResultUtil.isOpen(result, user);
        if (!result.getSuccess()) {
            return result;
        }

        // 用户基本信息
        User entity = new User();
        entity.setUserId(userId);
        entity.setUserName(userName);
        entity.setUserCard(userCard);
        entity.setTradePassword(tradePassword);
        // 银行卡信息
        UserBank bankEntity = new UserBank();
        bankEntity.setBankCode(bankCode);
        bankEntity.setBankName(bankName);
        bankEntity.setUserBankNo(userBankNo);
        bankEntity.setBranchbank(vcBranchbank);
        bankEntity.setBankBranchName(vcBankname);
        log.info("开户v3 联行号：{}，支行名称：{}", bankEntity.getBranchbank(), bankEntity.getBankBranchName());
        bankEntity.setUserBankMobile(userBankMobile);
        bankEntity.setUserId(userId);
        bankEntity.setUserBankOwner(userName);
        bankEntity.setCapitalMode(GlobalConstant.CAPITAL_MODE_EPAY);

        // 验证输入
        PaySignResult payResult;

        payResult = accountValidation.validateBankAddAccount(entity, bankEntity, originalSerialNo, smsSerialNo, mobileCode,
            isOpen);

        if (payResult != null) {
            return result;
        }

        //验证支行信息
        BaseResult baseResult;
        baseResult = accountValidation.validateBranch(bankEntity.getBranchbank());
        if (baseResult != null) {
            return baseResult;
        }

        // Step 1: 调用实名验证步骤二接口
        // 身份证转成大写
        entity.setUserCard(entity.getUserCard().toUpperCase());
        payResult = userService.paySign_Step_Two(entity, bankEntity, originalSerialNo, smsSerialNo, mobileCode);

        if (!payResult.getSuccess()) {
            if (StringUtil.isEmpty(payResult.getErrorMessage())) {
                payResult.setErrorMessage(MessageUtil.getErrorMessage(payResult.getErrorCode(), null));
            }
            return payResult;
        }

        // Step 2: 调用新增交易账号
        // 完成银行卡绑定
        result = userService.addAccount(userId, userCard, tradePassword, userName, bankCode, userBankNo, bankName,
            userBankMobile, GlobalConstant.CAPITAL_MODE_EPAY, payResult.getProtocolNo(), vcBranchbank, vcBankname);
        if (!result.getSuccess()) {
            if (StringUtil.isEmpty(result.getErrorMessage())) {
                result.setErrorMessage(MessageUtil.getErrorMessage(result.getErrorCode(), null));
            }
            return result;
        }
        return result;
    }

    /**
     * 绑卡-是否能够解绑银行卡
     */
    @PostMapping("/unbind_bank")
    @Loggable
    public BaseResult unbindBank(HttpServletRequest request, String bankAccount, String capitalMode) {
        Long userId = Long.valueOf(RequestUtils.getHeader(request, "userid"));
        return queryService.checkSharesExistByBankAccount(userId, bankAccount, capitalMode);
    }

    /**
     * 解绑银行卡
     */
    @PostMapping("/unbind_bank_sure")
    @Loggable
    public BaseResult unbindBankSure(String bankAccount, HttpServletRequest request, String tradePassword, String capitalMode) {
        Long userId = Long.valueOf(RequestUtils.getHeader(request, "userid"));
        User user = userService.getUser(userId);

        BaseResult result = new BaseResult();


        tradePassword = MD5.MD5Encode(tradePassword.trim());

        Map<String, Object> map = loginAcctService.login(tradePassword, user.getUserName(), user.getUserCard());

        // 查询结果
        if (!HsResponseUtil.isOperationOk(map)) {
            result.setSuccess(false);
            result.setErrorCode(FundErrorConst.TRADE_PWD_WRONG);
            result.setErrorMessage(MessageUtil.getErrorMsg(FundErrorConst.TRADE_PWD_WRONG));
            return result;
        }

        //执行解绑操作
        List<UserBank> userBanks = bankService.getBanks(userId, bankAccount);

        try {
            if (userBanks != null) {
                for (UserBank bank : userBanks) {
                    if (bank.getCapitalMode().equals(capitalMode)) {
                        //设置银行卡状态 注销
                        bank.setBankState("0");
                        bankService.updateByPrimaryKey(bank);
                    }
                }
            }
        } catch (Exception e) {
            log.error("解绑银行卡失败，h5接口:/h5/bank/unbind_bank_sure 错误信息:{}", e.getMessage());
        }
        return result;
    }

    /**
     * 检查银行卡数量
     */
    @GetMapping("/checkBankCardCounts")
    public BaseResult checkBankCardCounts(HttpServletRequest request) {
        Long userId = Long.valueOf(RequestUtils.getHeader(request, "userid"));
        List<UserBank> banks = bankService.getBankCardsNotInCounter(userId);
        BaseResult result = new BaseResult();
        if (banks != null) {
            if (banks.size() >= 5) {
                result.setSuccess(false);
                result.setErrorType(GlobalConstant.ERROR_TYPE_APPLICATION);
                result.setErrorCode(ErrorConstant.ERROR_BANK_COUNTS_MAX);
                result.setErrorMessage(MessageUtil.getErrorMsg(ErrorConstant.ERROR_BANK_COUNTS_MAX));
            }
        }
        return result;
    }

    /**
     * 点击下一步, 检查银行卡是否处在开户状态
     */
    @Loggable
    @GetMapping("/checkBankAccountStatus")
    public BaseResult checkBankStatus(HttpServletRequest request, String bankAccount) {
        BaseResult result = new BaseResult();
        Long userId = Long.valueOf(RequestUtils.getHeader(request, "userid"));
        if (StringUtil.isEmpty(bankAccount)) {
            result.setSuccess(false);
            result.setErrorCode(ErrorConstant.ERROR_FIELD_NO_FIND);
            Map<String, String> map = new HashMap<>();
            map.put(ErrorConstant.PLACEHOLDER_FIELD_NO_FIND_FIELD, "银行卡号");
            result.setErrorMessage(MessageUtil.getErrorMessage(ErrorConstant.ERROR_FIELD_NO_FIND, map));
            return result;
        }
        List<UserBank> userBanks = bankService.getBanks(userId, bankAccount.trim());
        UserBank userBank = null;
        if (userBanks != null) {
            for (UserBank bank : userBanks) {
                if (!"1".equals(bank.getCapitalMode())) {
                    userBank = bank;
                    break;
                }
            }
        }
        result.setResult(userBank);
        return result;
    }


    /**
     * 获得银行卡列表
     *
     * @param request
     * @return
     */
    @GetMapping("/get")
    @Loggable
    public BaseListResult getBanks(HttpServletRequest request) {
        BaseListResult result = null;
        Long userId = Long.valueOf(RequestUtils.getHeader(request, "userid"));
        // 获取客户编号
        User userEntity = userService.getUser(userId);
        if (userEntity == null) {
            result = new BankListResult();
            result.setSuccess(false);
            result.setErrorCode(ErrorConstant.ERROR_NO_USER_FIND);
            return result;
        }
        if (StringUtil.isEmpty(userEntity.getExternalClientId())) {
            result = new BankListResult();
            result.setSuccess(true);
        } else {

            List<UserBank> userBanks = bankService.getListByUserId(userId);

            if (ListUtil.isNotEmpty(userBanks)) {
                result = new BankListResult();
                result.setSuccess(true);

                List<BankModel> banks = new ArrayList<>(userBanks.size());
                userBanks.forEach(bank -> {
                    BankModel bankModel = new BankModel();
                    bankModel.setBranchBank(bank.getBranchbank() == null ? "" : bank.getBranchbank());
                    bankModel.setBranchBankName(bank.getBankBranchName() == null ? "" : bank.getBankBranchName());
                    bankModel.setBankName(bank.getBankName());
                    bankModel.setBankCode(bank.getBankCode());
                    bankModel.setUserBankNo(bank.getUserBankNo());
                    bankModel.setCapitalMode(bank.getCapitalMode());
                    bankModel.setTradeAccount(bank.getExternalTradeAccount());


                    banks.add(bankModel);
                });

                ((BankListResult) result).setBanks(banks);
            }
        }

        return result;
    }

    /**
     * 启用注销银行卡
     */
    @PostMapping("/activeBankAccount")
    @Loggable
    public BaseResult activeBankAccount(HttpServletRequest request, String bankAccount) {
        BaseResult result = new BaseResult();
        if (StringUtil.isEmpty(bankAccount)) {
            result.setErrorCode(ErrorConstant.ERROR_FIELD_NO_FIND);
            Map<String, String> map = new HashMap<>();
            map.put(ErrorConstant.PLACEHOLDER_FIELD_NO_FIND_FIELD, "银行卡号");
            result.setErrorMessage(MessageUtil.getErrorMessage(ErrorConstant.ERROR_FIELD_NO_FIND, map));
            result.setSuccess(false);
            return result;
        }
        Long userId = Long.valueOf(RequestUtils.getHeader(request, "userid"));
        List<UserBank> userBanks = bankService.getBanks(userId, bankAccount.trim());
        if (userBanks != null) {
            for (UserBank bank : userBanks) {
                if (!GlobalConstant.CAPITAL_MODE_COUNTER.equals(bank.getCapitalMode())) {
                    bank.setBankState("1");

                    bankService.updateByPrimaryKey(bank);
                }
            }
        }
        if (userBanks == null) {
            result.setSuccess(false);
            result.setErrorCode(ErrorConstant.ERROR_NO_BANK_CARD_FIND);
            result.setErrorMessage(MessageUtil.getErrorMsg(ErrorConstant.ERROR_NO_BANK_CARD_FIND));

            return result;
        }

        return result;
    }

}
